//
//  SLMP4Parser+Stbl.m
//  SLVideoParser
//
//  Created by S_LINE on 2020/6/20.
//  Copyright © 2020 S_LINE. All rights reserved.
//

#import "SLMP4Parser+Stbl.h"

#import "SLParserUtil.h"

@implementation SLMP4Parser (Stbl)

- (NSDictionary *)stsdParser:(NSData *)data
{
    if (data.length < 1)
    {
        return nil;
    }
    NSString *versionKey = @"version";
    NSString *flagsKey = @"flags";
    NSString *entryCountKey = @"entryCount";
    NSString *entryInfoKey = @"entryInfo";
    NSMutableDictionary *dict = [NSMutableDictionary new];
    NSData *versionData = [data subdataWithRange:NSMakeRange(0, 1)];
    uint64_t version = [SLParserUtil hexToDecimalWithData:versionData];
    [dict setObject:[NSNumber numberWithUnsignedLongLong:version] forKey:versionKey];
    uint64_t offset = 1;
    
    if (version == 0)
    {
        uint64_t flagsSize = 3;
        NSData *flagsData = [data subdataWithRange:NSMakeRange(offset, flagsSize)];
        uint64_t flags = [SLParserUtil hexToDecimalWithData:flagsData];
        offset += flagsSize;
        // entry count “url”或“urn”表的元素个数
        uint64_t entryCountSize = 4;
        NSData *entryCountData = [data subdataWithRange:NSMakeRange(offset, entryCountSize)];
        uint64_t entryCount = [SLParserUtil hexToDecimalWithData:entryCountData];
        offset += entryCountSize;
        // “url”或“urn”列表
        NSMutableArray *urlArray = [NSMutableArray new];
        for (int i = 0; i < entryCount; i++)
        {
            uint64_t sizeSize = 4;
            NSData *sizeData = [data subdataWithRange:NSMakeRange(offset, sizeSize)];
            uint64_t size = [SLParserUtil hexToDecimalWithData:sizeData];
            uint64_t offsetEnd = offset + size;
            offset += sizeSize;
            
            uint64_t typeSize = 4;
            NSData *typeData = [data subdataWithRange:NSMakeRange(offset, typeSize)];
            NSString *type = [SLParserUtil hexToStringTypeWithData:typeData];
            offset += typeSize;
            
            offset += 2;
            uint64_t refrenceSize = 2;
            NSData *refrenceData = [data subdataWithRange:NSMakeRange(offset, refrenceSize)];
            uint64_t refrence = [SLParserUtil hexToDecimalWithData:refrenceData];
            
            [urlArray addObject:[NSString stringWithFormat:@"size: %llu, type: %@, refrence: %llu", size, type, refrence]];
            
            offset = offsetEnd;
        }
        
        [dict setObject:[NSNumber numberWithUnsignedLongLong:flags] forKey:flagsKey];
        [dict setObject:[NSNumber numberWithUnsignedLongLong:entryCount] forKey:entryCountKey];
        [dict setObject:urlArray forKey:entryInfoKey];
    }
    
    return [dict copy];
}

- (NSDictionary *)sttsParser:(NSData *)data
{
    if (data.length < 1)
    {
        return nil;
    }
    NSString *versionKey = @"version";
    NSString *flagsKey = @"flags";
    NSString *entryCountKey = @"entryCount";
    NSString *entryInfoKey = @"entryInfo";
    NSString *durationKey = @"duration";
    NSMutableDictionary *dict = [NSMutableDictionary new];
    NSData *versionData = [data subdataWithRange:NSMakeRange(0, 1)];
    uint64_t version = [SLParserUtil hexToDecimalWithData:versionData];
    [dict setObject:[NSNumber numberWithUnsignedLongLong:version] forKey:versionKey];
    uint64_t offset = 1;
    
    if (version == 0)
    {
        uint64_t flagsSize = 3;
        NSData *flagsData = [data subdataWithRange:NSMakeRange(offset, flagsSize)];
        uint64_t flags = [SLParserUtil hexToDecimalWithData:flagsData];
        offset += flagsSize;
        // entry count “url”或“urn”表的元素个数
        uint64_t entryCountSize = 4;
        NSData *entryCountData = [data subdataWithRange:NSMakeRange(offset, entryCountSize)];
        uint64_t entryCount = [SLParserUtil hexToDecimalWithData:entryCountData];
        offset += entryCountSize;
        
        // 
        NSMutableArray *array = [NSMutableArray new];
        uint64_t duration = 0;
        for (int i = 0; i < entryCount; i++)
        {
            // 有相同duration的连续sample的数目
            uint64_t sampleCountSize = 4;
            NSData *sampleCountData = [data subdataWithRange:NSMakeRange(offset, sampleCountSize)];
            uint64_t sampleCount = [SLParserUtil hexToDecimalWithData:sampleCountData];
            offset += sampleCountSize;
            // 每个sample的duration
            uint64_t sampleDurationSize = 4;
            NSData *sampleDurationData = [data subdataWithRange:NSMakeRange(offset, sampleDurationSize)];
            uint64_t sampleDuration = [SLParserUtil hexToDecimalWithData:sampleDurationData];
            offset += sampleDurationSize;
            duration = duration + sampleCount * sampleDuration;
            
            [array addObject:@{@"sampleCount": [NSNumber numberWithUnsignedLongLong:sampleCount], @"sampleDuration": [NSNumber numberWithUnsignedLongLong:sampleDuration]}];
        }
        
        [dict setObject:[NSNumber numberWithUnsignedLongLong:flags] forKey:flagsKey];
        [dict setObject:[NSNumber numberWithUnsignedLongLong:entryCount] forKey:entryCountKey];
        [dict setObject:array forKey:entryInfoKey];
        [dict setObject:[NSNumber numberWithUnsignedLongLong:duration] forKey:durationKey];
    }
    
    return [dict copy];
}

- (NSDictionary *)stssParser:(NSData *)data
{
    if (data.length < 1)
    {
        return nil;
    }
    NSString *versionKey = @"version";
    NSString *flagsKey = @"flags";
    NSString *entryCountKey = @"entryCount";
    NSString *entryInfoKey = @"entryInfo";
    NSMutableDictionary *dict = [NSMutableDictionary new];
    NSData *versionData = [data subdataWithRange:NSMakeRange(0, 1)];
    uint64_t version = [SLParserUtil hexToDecimalWithData:versionData];
    [dict setObject:[NSNumber numberWithUnsignedLongLong:version] forKey:versionKey];
    uint64_t offset = 1;
    
    if (version == 0)
    {
        uint64_t flagsSize = 3;
        NSData *flagsData = [data subdataWithRange:NSMakeRange(offset, flagsSize)];
        uint64_t flags = [SLParserUtil hexToDecimalWithData:flagsData];
        offset += flagsSize;
        // entry count “url”或“urn”表的元素个数
        uint64_t entryCountSize = 4;
        NSData *entryCountData = [data subdataWithRange:NSMakeRange(offset, entryCountSize)];
        uint64_t entryCount = [SLParserUtil hexToDecimalWithData:entryCountData];
        offset += entryCountSize;
        
        NSMutableArray *array = [NSMutableArray new];
        for (int i = 0; i < entryCount; i++)
        {
            // 是关键帧的sample序号
            uint64_t sampleSequenceSize = 4;
            NSData *sampleSequenceData = [data subdataWithRange:NSMakeRange(offset, sampleSequenceSize)];
            uint64_t sampleSequence = [SLParserUtil hexToDecimalWithData:sampleSequenceData];
            offset += sampleSequenceSize;
            
            [array addObject:@{@"sampleSequence": [NSNumber numberWithUnsignedLongLong:sampleSequence]}];
        }
        
        [dict setObject:[NSNumber numberWithUnsignedLongLong:flags] forKey:flagsKey];
        [dict setObject:[NSNumber numberWithUnsignedLongLong:entryCount] forKey:entryCountKey];
        [dict setObject:array forKey:entryInfoKey];
    }
    
    return [dict copy];
}

- (NSDictionary *)stscParser:(NSData *)data
{
    if (data.length < 1)
    {
        return nil;
    }
    NSString *versionKey = @"version";
    NSString *flagsKey = @"flags";
    NSString *entryCountKey = @"entryCount";
    NSString *entryInfoKey = @"entryInfo";
    NSMutableDictionary *dict = [NSMutableDictionary new];
    NSData *versionData = [data subdataWithRange:NSMakeRange(0, 1)];
    uint64_t version = [SLParserUtil hexToDecimalWithData:versionData];
    [dict setObject:[NSNumber numberWithUnsignedLongLong:version] forKey:versionKey];
    uint64_t offset = 1;
    
    if (version == 0)
    {
        uint64_t flagsSize = 3;
        NSData *flagsData = [data subdataWithRange:NSMakeRange(offset, flagsSize)];
        uint64_t flags = [SLParserUtil hexToDecimalWithData:flagsData];
        offset += flagsSize;
        // entry count
        uint64_t entryCountSize = 4;
        NSData *entryCountData = [data subdataWithRange:NSMakeRange(offset, entryCountSize)];
        uint64_t entryCount = [SLParserUtil hexToDecimalWithData:entryCountData];
        offset += entryCountSize;
        
        NSMutableArray *array = [NSMutableArray new];
        for (int i = 0; i < entryCount; i++)
        {
            // 这个table使用的第一个chunk序号
            uint64_t firstChunkSize = 4;
            NSData *firstChunkData = [data subdataWithRange:NSMakeRange(offset, firstChunkSize)];
            uint64_t firstChunk = [SLParserUtil hexToDecimalWithData:firstChunkData];
            offset += firstChunkSize;
            // 当前trunk内的sample数目
            uint64_t samplesPerChunkSize = 4;
            NSData *samplesPerChunkData = [data subdataWithRange:NSMakeRange(offset, samplesPerChunkSize)];
            uint64_t samplesPerChunk = [SLParserUtil hexToDecimalWithData:samplesPerChunkData];
            offset += samplesPerChunkSize;
            // 与这些sample关联的sample description的序号
            uint64_t sampleDescriptionIDSize = 4;
            NSData *sampleDescriptionIDData = [data subdataWithRange:NSMakeRange(offset, sampleDescriptionIDSize)];
            uint64_t sampleDescriptionID = [SLParserUtil hexToDecimalWithData:sampleDescriptionIDData];
            offset += sampleDescriptionIDSize;
            
            [array addObject:@{@"firstChunk": [NSNumber numberWithUnsignedLongLong:firstChunk], @"samplesPerChunk": [NSNumber numberWithUnsignedLongLong:samplesPerChunk], @"sampleDescriptionID": [NSNumber numberWithUnsignedLongLong:sampleDescriptionID]}];
        }
        
        [dict setObject:[NSNumber numberWithUnsignedLongLong:flags] forKey:flagsKey];
        [dict setObject:[NSNumber numberWithUnsignedLongLong:entryCount] forKey:entryCountKey];
        [dict setObject:array forKey:entryInfoKey];
    }
    
    return [dict copy];
}

- (NSDictionary *)stszParser:(NSData *)data
{
    if (data.length < 1)
    {
        return nil;
    }
    NSString *versionKey = @"version";
    NSString *flagsKey = @"flags";
    NSString *entryCountKey = @"entryCount";
    NSString *entryInfoKey = @"entryInfo";
    NSString *sampleSizeKey = @"sampleSize";
    NSMutableDictionary *dict = [NSMutableDictionary new];
    NSData *versionData = [data subdataWithRange:NSMakeRange(0, 1)];
    uint64_t version = [SLParserUtil hexToDecimalWithData:versionData];
    [dict setObject:[NSNumber numberWithUnsignedLongLong:version] forKey:versionKey];
    uint64_t offset = 1;
    
    if (version == 0)
    {
        uint64_t flagsSize = 3;
        NSData *flagsData = [data subdataWithRange:NSMakeRange(offset, flagsSize)];
        uint64_t flags = [SLParserUtil hexToDecimalWithData:flagsData];
        offset += flagsSize;
        // sample size 全部sample的数目。如果所有的sample有相同的长度，这个字段就是这个值。否则，这个字段的值就是0。那些长度存在sample size表中
        uint64_t sampleSizeSize = 4;
        NSData *sampleSizeData = [data subdataWithRange:NSMakeRange(offset, sampleSizeSize)];
        uint64_t sampleSize = [SLParserUtil hexToDecimalWithData:sampleSizeData];
        offset += sampleSizeSize;
        
        if (sampleSize == 0)
        {
            // entry count
            uint64_t entryCountSize = 4;
            NSData *entryCountData = [data subdataWithRange:NSMakeRange(offset, entryCountSize)];
            uint64_t entryCount = [SLParserUtil hexToDecimalWithData:entryCountData];
            offset += entryCountSize;
            
            NSMutableArray *array = [NSMutableArray new];
            for (int i = 0; i < entryCount; i++)
            {
                uint64_t sampleSubSizeSize = 4;
                NSData *sampleSubSizeData = [data subdataWithRange:NSMakeRange(offset, sampleSubSizeSize)];
                uint64_t sampleSubSize = [SLParserUtil hexToDecimalWithData:sampleSubSizeData];
                offset += sampleSubSizeSize;
                sampleSize += sampleSubSize;
                
                [array addObject:@{@"sampleSubSize": [NSNumber numberWithUnsignedLongLong:sampleSubSize]}];
            }

            [dict setObject:[NSNumber numberWithUnsignedLongLong:entryCount] forKey:entryCountKey];
            [dict setObject:array forKey:entryInfoKey];
        }
        
        [dict setObject:[NSNumber numberWithUnsignedLongLong:flags] forKey:flagsKey];
        [dict setObject:[NSNumber numberWithUnsignedLongLong:sampleSize] forKey:sampleSizeKey];
    }
    
    return [dict copy];
}

- (NSDictionary *)stcoParser:(NSData *)data
{
    if (data.length < 1)
    {
        return nil;
    }
    NSString *versionKey = @"version";
    NSString *flagsKey = @"flags";
    NSString *entryCountKey = @"entryCount";
    NSString *entryInfoKey = @"entryInfo";
    NSMutableDictionary *dict = [NSMutableDictionary new];
    NSData *versionData = [data subdataWithRange:NSMakeRange(0, 1)];
    uint64_t version = [SLParserUtil hexToDecimalWithData:versionData];
    [dict setObject:[NSNumber numberWithUnsignedLongLong:version] forKey:versionKey];
    uint64_t offset = 1;
    
    if (version == 0)
    {
        uint64_t flagsSize = 3;
        NSData *flagsData = [data subdataWithRange:NSMakeRange(offset, flagsSize)];
        uint64_t flags = [SLParserUtil hexToDecimalWithData:flagsData];
        offset += flagsSize;
        // entry count
        uint64_t entryCountSize = 4;
        NSData *entryCountData = [data subdataWithRange:NSMakeRange(offset, entryCountSize)];
        uint64_t entryCount = [SLParserUtil hexToDecimalWithData:entryCountData];
        offset += entryCountSize;
        
        NSMutableArray *array = [NSMutableArray new];
        // 字节偏移量从文件开始到当前chunk。这个表根据chunk number索引，第一项就是第一个trunk，第二项就是第二个trunk
        for (int i = 0; i < entryCount; i++)
        {
            // 每个sample的大小
            uint64_t chunkOffsetSize = 4;
            NSData *chunkOffsetData = [data subdataWithRange:NSMakeRange(offset, chunkOffsetSize)];
            uint64_t chunkOffset = [SLParserUtil hexToDecimalWithData:chunkOffsetData];
            offset += chunkOffsetSize;
            
            [array addObject:@{@"chunkOffset": [NSNumber numberWithUnsignedLongLong:chunkOffset]}];
        }
        
        [dict setObject:[NSNumber numberWithUnsignedLongLong:flags] forKey:flagsKey];
        [dict setObject:[NSNumber numberWithUnsignedLongLong:entryCount] forKey:entryCountKey];
        [dict setObject:array forKey:entryInfoKey];
    }
    
    return [dict copy];
}

@end
